home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 7 / Night Owl Shareware (NOPV7)(Night Owl Publisher Inc.)(1992).bin / 038a / bash1_12.arj / BASH1-12.TAR / bash-1.12 / builtins / declare.def < prev    next >
Text File  |  1991-11-07  |  7KB  |  279 lines

  1. This file is declare.def, from which is created declare.c.
  2. It implements the builtins "declare" and "local" in Bash.
  3.  
  4. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
  5.  
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7.  
  8. Bash is free software; you can redistribute it and/or modify it under
  9. the terms of the GNU General Public License as published by the Free
  10. Software Foundation; either version 1, or (at your option) any later
  11. version.
  12.  
  13. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  14. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License along
  19. with Bash; see the file COPYING.  If not, write to the Free Software
  20. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. $PRODUCES declare.c
  23.  
  24. $BUILTIN declare
  25. $FUNCTION declare_builtin
  26. $SHORT_DOC declare [-[frxi]] name[=value] ...
  27. Declare variables and/or give them attributes.  If no NAMEs are
  28. given, then display the values of variables instead.
  29.  
  30. The flags are:
  31.  
  32.   -f    to select from among function names only,
  33.   -r    to make NAMEs readonly,
  34.   -x    to make NAMEs export,
  35.   -i    to make NAMEs have the `integer' attribute set.
  36.  
  37. Variables with the integer attribute have arithmetic evaluation (see
  38. `let') done when the variable is assigned to.
  39.  
  40. Using `+' instead of `-' turns off the given attribute instead.  When
  41. used in a function, makes NAMEs local, as with the `local' command.
  42. $END
  43.  
  44. $BUILTIN typeset
  45. $FUNCTION declare_builtin
  46. $SHORT_DOC typeset [-[frxi]] name[=value] ...
  47. Obsolete.  See `declare'.
  48. $END
  49.  
  50. #include <stdio.h>
  51. #include "../shell.h"
  52.  
  53. static int declare_internal ();
  54.  
  55. /* Declare or change variable attributes. */
  56. int
  57. declare_builtin (list)
  58.      register WORD_LIST *list;
  59. {
  60.   return (declare_internal (list, 0));
  61. }
  62.  
  63. $BUILTIN local
  64. $FUNCTION local_builtin
  65. $SHORT_DOC local name[=value] ...
  66. Create a local variable called NAME, and give it VALUE.  LOCAL
  67. can only be used within a function; it makes the variable NAME
  68. have a visible scope restricted to that function and its children.
  69. $END
  70. int
  71. local_builtin (list)
  72.      register WORD_LIST *list;
  73. {
  74.   extern int variable_context;
  75.  
  76.   if (variable_context)
  77.     return (declare_internal (list, 1));
  78.   else
  79.     {
  80.       builtin_error ("Can only be used in a function");
  81.       return (EXECUTION_FAILURE);
  82.     }
  83. }
  84.  
  85. /* The workhorse function. */
  86. static int
  87. declare_internal (list, no_modifiers)
  88.      register WORD_LIST *list;
  89.      int no_modifiers;
  90. {
  91.   extern int variable_context, array_needs_making;
  92.   int flags_on = 0, flags_off = 0;
  93.   int any_failed = 0;
  94.  
  95.   while (list)
  96.     {
  97.       register char *t = list->word->word;
  98.       int *flags;
  99.  
  100.       if (strcmp (t, "--") == 0)
  101.     {
  102.       list = list->next;
  103.       break;
  104.     }
  105.  
  106.       if (*t != '+' && *t != '-')
  107.     break;
  108.  
  109.       if (no_modifiers)
  110.     {
  111.       builtin_error ("Modifiers not allowed");
  112.       return (EXECUTION_FAILURE);
  113.     }
  114.  
  115.       if (*t == '+')
  116.     flags = &flags_off;
  117.       else
  118.     flags = &flags_on;
  119.  
  120.       t++;
  121.  
  122.       while (*t)
  123.     {
  124.       if (*t == 'f')
  125.         *flags |= att_function, t++;
  126.       else if (*t == 'x')
  127.         *flags |= att_exported, t++, array_needs_making = 1;
  128.       else if (*t == 'r')
  129.         *flags |= att_readonly, t++;
  130.       else if (*t == 'i')
  131.         *flags |= att_integer, t++;
  132.       else
  133.         {
  134.           builtin_error ("unknown option: `-%c'", *t);
  135.           return (EXECUTION_FAILURE);
  136.         }
  137.     }
  138.  
  139.       list = list->next;
  140.     }
  141.  
  142.   /* If there are no more arguments left, then we just want to show
  143.      some variables. */
  144.   if (!list)
  145.     {
  146.       /* If we didn't allow modifiers, then this is the `local' command.
  147.      Perhaps the flag should be called `local_command' instead of
  148.      `no_modifiers'.  At any rate, only show local variables defined
  149.      at this context level. */
  150.       if (no_modifiers)
  151.     {
  152.       register SHELL_VAR **vlist;
  153.       register int i;
  154.  
  155.       vlist = map_over (variable_in_context, shell_variables);
  156.  
  157.       if (vlist)
  158.         {
  159.           for (i = 0; vlist[i]; i++)
  160.         print_assignment (vlist[i]);
  161.  
  162.           free (vlist);
  163.         }
  164.     }
  165.       else
  166.     {
  167.       if (!flags_on)
  168.         set_builtin ((WORD_LIST *)NULL);
  169.       else
  170.         set_or_show_attributes ((WORD_LIST *)NULL, flags_on);
  171.     }
  172.  
  173.       fflush (stdout);
  174.       return (EXECUTION_SUCCESS);
  175.     }
  176.  
  177.   /* There are arguments left, so we are making variables. */
  178.   while (list)
  179.     {
  180.       char *value, *name = savestring (list->word->word);
  181.       int offset = assignment (name);
  182.  
  183.       if (offset)
  184.     {
  185.       name[offset] = '\0';
  186.       value = name + offset + 1;
  187.     }
  188.       else
  189.     {
  190.       value = "";
  191.     }
  192.  
  193.       /* If VARIABLE_CONTEXT has a non-zero value, then we are executing
  194.      inside of a function.  This means we should make local variables,
  195.      not global ones. */
  196.  
  197.       if (variable_context)
  198.     make_local_variable (name);
  199.  
  200.       /* If we are declaring a function, then complain about it in some way.
  201.      We don't let people make functions by saying `typeset -f foo=bar'. */
  202.  
  203.       /* There should be a way, however, to let people look at a particular
  204.      function definition by saying `typeset -f foo'. */
  205.  
  206.       if (flags_on & att_function)
  207.     {
  208.       if (offset)
  209.         {
  210.           builtin_error ("Can't use `-f' to make functions");
  211.           return (EXECUTION_FAILURE);
  212.         }
  213.       else
  214.         {
  215.           SHELL_VAR *find_function (), *funvar;
  216.           funvar = find_function (name);
  217.  
  218.           if (funvar)
  219.         {
  220.           extern char *named_function_string ();
  221.           char *result = named_function_string
  222.             (name, (COMMAND *)function_cell (funvar), 1);
  223.           printf ("%s\n", result);
  224.         }
  225.           else
  226.         any_failed++;
  227.           goto hack_next_variable;
  228.         }
  229.     }
  230.       else
  231.     {
  232.       SHELL_VAR *var;
  233.  
  234.       var = find_variable (name);
  235.  
  236.       if (!var)
  237.         var = bind_variable (name, "");
  238.  
  239.       /* We are not allowed to rebind readonly variables that
  240.          already are readonly unless we are turning off the
  241.          readonly bit. */
  242.       if (flags_off & att_readonly)
  243.         flags_on &= ~att_readonly;
  244.  
  245.       if (value && readonly_p (var) && (!(flags_off & att_readonly)))
  246.         {
  247.           builtin_error ("%s: readonly variable", name);
  248.           any_failed++;
  249.           goto hack_next_variable;
  250.         }
  251.  
  252.       var->attributes |= flags_on;
  253.       var->attributes &= ~flags_off;
  254.  
  255.       if (offset)
  256.         {
  257.           free (var->value);
  258.           if (integer_p (var))
  259.         {
  260.           long val, evalexp ();
  261.           char *itos ();
  262.  
  263.           val = evalexp (value);
  264.           var->value = itos ((int)val);
  265.         }
  266.           else
  267.         var->value = savestring (value);
  268.         }
  269.     }
  270.  
  271.       stupidly_hack_special_variables (name);
  272.  
  273.     hack_next_variable:
  274.       free (name);
  275.       list = list->next;
  276.     }
  277.   return ((!any_failed) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
  278. }
  279.